<template>
	<div>
		<el-dialog title="任务监听器" width="900px" draggable v-bind="$attrs">
			<div class="p-b-10">
				<my-button type="primary" @click="formData.taskListener.push({})" icon="Plus">新增</my-button>
			</div>
			<el-form ref="formRef" :model="formData" label-width="0" inline-message>
				<my-table
					:data="formData.taskListener"
					:columns="[
						{
							label: '事件',
							prop: 'event'
						},
						{
							label: '类型',
							prop: 'type'
						},
						{
							label: '值',
							prop: 'className'
						},
						{
							label: '操作',
							fixed: 'right',
							width: '70'
						}
					]"
					height="250"
				>
					<template #event_header="scope">
						{{ scope.label }}
						<el-tooltip
							content="create（创建）：当任务已经创建，并且所有任务参数都已经设置时触发。<br />
                                    assignment（指派）：当任务已经指派给某人时触发。请注意：当流程执行到达用户任务时，在触发create事件之前，会首先触发assignment事件。<br />
                                    complete（完成）：当任务已经完成，从运行时数据中删除前触发。<br />
                                    delete（删除）：在任务即将被删除前触发。请注意任务由completeTask正常完成时也会触发。"
							placement="top"
							raw-content
						>
							<my-icon icon="QuestionFilled" color="var(--el-color-primary)" />
						</el-tooltip>
					</template>
					<template #event="{ row, $index, prop }">
						<el-form-item
							:prop="`taskListener.${$index}.${prop}`"
							:rules="[{ required: true, message: '请选择', trigger: ['blur', 'change'] }]"
							v-if="$index >= 0"
						>
							<my-select
								v-model="row[prop]"
								:list="[
									{ label: 'create', value: 'create' },
									{ label: 'assignment', value: 'assignment' },
									{ label: 'complete', value: 'complete' },
									{ label: 'delete', value: 'delete' }
								]"
								:fileType="{ label: 'label', value: 'value' }"
							/>
						</el-form-item>
					</template>

					<template #type_header="scope">
						{{ scope.label }}
						<el-tooltip
							content="类：示例 com.company.MyCustomListener，自定义类必须实现 org.flowable.engine.delegate.TaskListener 接口 <br />
                                    表达式：示例 \${myObject.callMethod(task, task.eventName)} <br />
                                    委托表达式：示例 \${myListenerSpringBean} ，该 springBean 需要实现 org.flowable.engine.delegate.TaskListener 接口"
							placement="top"
							raw-content
						>
							<my-icon icon="QuestionFilled" color="var(--el-color-primary)" />
						</el-tooltip>
					</template>
					<template #type="{ row, $index, prop }">
						<el-form-item
							:prop="`taskListener.${$index}.${prop}`"
							:rules="[{ required: true, message: '请选择', trigger: ['blur', 'change'] }]"
							v-if="$index >= 0"
						>
							<my-select
								v-model="row[prop]"
								:list="[
									{ label: '类', value: 'class' },
									{ label: '表达式', value: 'expression' },
									{ label: '委托表达式', value: 'delegateExpression' }
								]"
								:fileType="{ label: 'label', value: 'value' }"
							/>
						</el-form-item>
					</template>
					<template #className="{ row, $index, prop }">
						<el-form-item
							:prop="`taskListener.${$index}.${prop}`"
							:rules="[{ required: true, message: '请输入', trigger: ['blur', 'change'] }]"
							v-if="$index >= 0"
						>
							<my-input v-model="row[prop]" />
						</el-form-item>
					</template>
					<template #default="{ $index }">
						<my-button-text @click="formData.executionListener.splice($index)">删除</my-button-text>
					</template>
				</my-table>
			</el-form>
			<template #footer>
				<my-button @click.prevent="$attrs['onUpdate:modelValue'](false)">取 消</my-button>
				<el-button type="primary" @click.prevent="() => closeDialog().then(() => $attrs['onUpdate:modelValue'](false))">确 定</el-button>
			</template>
		</el-dialog>
	</div>
</template>

<script setup>
function GENG(data) {
	draggable;
}
import hooksPanel, { PanelProps } from '../../common/Panel';

const props = defineProps({
		...PanelProps
	}),
	{ formData, updateProperties } = hooksPanel(props);

onMounted(() => {
	formData.value.taskListener =
		props.element.businessObject.extensionElements?.values
			.filter((item) => item.$type === 'flowable:TaskListener')
			.map((item) => {
				let type;
				if ('class' in item) type = 'class';
				if ('expression' in item) type = 'expression';
				if ('delegateExpression' in item) type = 'delegateExpression';
				return {
					event: item.event,
					type: type,
					className: item[type],
					params:
						item.fields?.map((field) => {
							let fieldType;
							if ('stringValue' in field) fieldType = 'stringValue';
							if ('expression' in field) fieldType = 'expression';
							return {
								name: field.name,
								type: fieldType,
								value: field[fieldType]
							};
						}) ?? []
				};
			}) ?? [];
});

function updateElement() {
	if (formData.value.taskListener?.length) {
		let extensionElements = props.element.businessObject.get('extensionElements');
		if (!extensionElements) {
			extensionElements = props.modeler.get('moddle').create('bpmn:ExtensionElements');
		}
		// 清除旧值
		extensionElements.values = extensionElements.values?.filter((item) => item.$type !== 'flowable:TaskListener') ?? [];
		formData.value.taskListener.forEach((item) => {
			const taskListener = props.modeler.get('moddle').create('flowable:TaskListener');
			taskListener['event'] = item.event;
			taskListener[item.type] = item.className;
			if (item.params && item.params.length) {
				item.params.forEach((field) => {
					const fieldElement = props.modeler.get('moddle').create('flowable:Field');
					fieldElement['name'] = field.name;
					fieldElement[field.type] = field.value;
					// 注意：flowable.json 中定义的string和expression类为小写，不然会和原生的String类冲突，此处为hack
					// const valueElement = props.modeler.get('moddle').create(`flowable:${field.type}`, { body: field.value })
					// fieldElement[field.type] = valueElement
					taskListener.get('fields').push(fieldElement);
				});
			}
			extensionElements.get('values').push(taskListener);
		});
		updateProperties({ extensionElements: extensionElements });
	} else {
		const extensionElements = props.element.businessObject[`extensionElements`];
		if (extensionElements) {
			extensionElements.values = extensionElements.values?.filter((item) => item.$type !== 'flowable:TaskListener') ?? [];
		}
	}
}
const formRef = ref(null);
function closeDialog() {
	return formRef.value
		.validate()
		.then(() => {
			updateElement();
		})
		.catch((e) => console.error(e));
}
</script>
